home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Dev / Mui / Mcc_speedbar.lha / MCC_SpeedBar / Developer / C / Examples / barclass.c next >
C/C++ Source or Header  |  2002-12-21  |  11KB  |  391 lines

  1.  
  2. #include "barclass.h"
  3.  
  4. /***********************************************************************/
  5.  
  6. #define BOOLSAME(a,b) (((a) ? TRUE : FALSE)==((b) ? TRUE : FALSE))
  7.  
  8. /***********************************************************************/
  9. /*
  10. ** Utilility functions
  11. */
  12.  
  13. static ULONG STDARGS
  14. DoSuperNew(struct IClass *cl,Object *obj,ULONG tag1,...)
  15. {
  16.     return DoSuperMethod(cl,obj,OM_NEW,&tag1,NULL);
  17. }
  18.  
  19. /***********************************************************************/
  20. /*
  21. ** Bar Class data
  22. */
  23.  
  24. struct special
  25. {
  26.     ULONG exclude;
  27.     ULONG flags;
  28. };
  29.  
  30. enum
  31. {
  32.     SFLG_Skip     = 1<<0,
  33.     SFLG_Disabled = 1<<1,
  34. };
  35.  
  36. struct data
  37. {
  38.     struct special *specials;
  39.     ULONG          nb;
  40.     ULONG          active;
  41.     ULONG          flags;
  42. };
  43.  
  44. enum
  45. {
  46.     FLG_Disabled = 1<<0,
  47. };
  48.  
  49. /***********************************************************************/
  50. /*
  51. ** Bar Class New method
  52. */
  53.  
  54. static ASM ULONG
  55. mNew(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opSet *msg)
  56. {
  57.     register struct SBButton             *source, *s;
  58.     register struct MUIS_SpeedBar_Button *buttons;
  59.     register struct special              *specials;
  60.     register struct TagItem              *attrs = msg->ops_AttrList;
  61.     register STRPTR                      *pics;
  62.     register int                         nb, i, j;
  63.  
  64.     /* First sanity check */
  65.     if (!(source = (struct SBButton *)GetTagData(MUIA_Bar_Buttons,NULL,attrs)))
  66.         return 0;
  67.  
  68.     /* Counts buttons */
  69.     for (nb = 1, s = source; s->file!=(STRPTR)MUIV_SpeedBar_End; s++, nb++);
  70.  
  71.     /* Alloc buttons, specials and pics */
  72.     if (!(buttons = AllocVec((sizeof(STRPTR)+sizeof(struct MUIS_SpeedBar_Button))*nb,MEMF_ANY|MEMF_CLEAR)) ||
  73.         !(specials = AllocVec(sizeof(struct special)*nb,MEMF_ANY|MEMF_CLEAR)))
  74.     {
  75.         if (buttons) FreeVec(buttons);
  76.         return 0;
  77.     }
  78.  
  79.     pics = (STRPTR *)((UBYTE *)buttons+sizeof(struct MUIS_SpeedBar_Button)*nb);
  80.  
  81.     /* Fill structures */
  82.     for (i = j = 0, s = source; i<nb; i++)
  83.     {
  84.         if (s[i].file==(STRPTR)MUIV_SpeedBar_Spacer)
  85.         {
  86.             buttons[i].Img = MUIV_SpeedBar_Spacer;
  87.             specials[i].flags |= SFLG_Skip;
  88.             continue;
  89.         }
  90.  
  91.         if (s[i].file==(STRPTR)MUIV_SpeedBar_End)
  92.         {
  93.             buttons[i].Img = MUIV_SpeedBar_End;
  94.             continue;
  95.         }
  96.  
  97.         pics[j] = s[i].file;
  98.  
  99.         buttons[i].Img   = j++;
  100.         buttons[i].Text  = s[i].text;
  101.         buttons[i].Help  = s[i].help;
  102.         buttons[i].Flags = s[i].flags;
  103.  
  104.         if (specials[i].exclude = s[i].exclude)
  105.         {
  106.             buttons[i].Flags |= MUIV_SpeedBar_ButtonFlag_Immediate;
  107.             buttons[i].Flags &= ~MUIV_SpeedBar_ButtonFlag_Toggle;
  108.         }
  109.     }
  110.  
  111.     /* Create the bar */
  112.     if (obj = (Object *)DoSuperNew(cl,obj,
  113.             MUIA_Group_Horiz,               TRUE,
  114.             MUIA_SpeedBar_Buttons,          buttons,
  115.             MUIA_SpeedBar_Pics,             pics,
  116.             MUIA_SpeedBar_StripUnderscore,  TRUE,
  117.             MUIA_SpeedBar_EnableUnderscore, TRUE,
  118.             MUIA_SpeedBar_SpacerIndex,      -1,
  119.             TAG_MORE,attrs))
  120.     {
  121.         register struct data    *data = INST_DATA(cl,obj);
  122.         register ULONG          sel = -1;
  123.  
  124.         data->nb       = nb;
  125.         data->specials = specials;
  126.         data->active   = -1;
  127.  
  128.         /* Set up mutual exclude notifications */
  129.         for (i = 0; i<nb; i++)
  130.         {
  131.             if (specials[i].exclude)
  132.             {
  133.                 DoMethod(buttons[i].Object,MUIM_Notify,MUIA_Selected,TRUE,obj,2,MUIM_Bar_Active,i);
  134.                 if (buttons[i].Flags & MUIV_SpeedBar_ButtonFlag_Selected) sel = i;
  135.             }
  136.         }
  137.  
  138.         if (sel>=0) nfset(obj,MUIA_Bar_Active,sel);
  139.     }
  140.     else FreeVec(specials);
  141.  
  142.     /* Buttons is not needed anymore */
  143.     FreeVec(buttons);
  144.  
  145.     return (ULONG)obj;
  146. }
  147.  
  148. /***********************************************************************/
  149. /*
  150. ** Bar Class OM_GET
  151. */
  152.  
  153. static ASM ULONG
  154. mGet(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opGet *msg)
  155. {
  156.     register struct data *data = INST_DATA(cl,obj);
  157.  
  158.     switch (msg->opg_AttrID)
  159.     {
  160.         case MUIA_Bar_Active: *msg->opg_Storage = data->active; return TRUE;
  161.         default: return DoSuperMethodA(cl,obj,(Msg)msg);
  162.     }
  163. }
  164.  
  165. /***********************************************************************/
  166. /*
  167. ** Bar Class OM_SET method
  168. */
  169.  
  170. static ASM ULONG
  171. mSets(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct opSet *msg)
  172. {
  173.     register struct data    *data = INST_DATA(cl,obj);
  174.     register struct TagItem *tag;
  175.     struct TagItem          *tstate;
  176.     register ULONG          nb = data->nb;
  177.  
  178.     for (tstate = msg->ops_AttrList; tag = NextTagItem(&tstate); )
  179.     {
  180.         register ULONG tidata = tag->ti_Data;
  181.  
  182.         switch(tag->ti_Tag)
  183.         {
  184.             case MUIA_Bar_Active:
  185.             {
  186.                 register struct data    *data = INST_DATA(cl,obj);
  187.                 register ULONG          button = tidata, exclude;
  188.                 register Object         *o;
  189.                 register int            i;
  190.  
  191.                 if (data->active==button || button<0 || button>nb-1 || !(exclude = data->specials[button].exclude))
  192.                 {
  193.                     tag->ti_Tag = TAG_IGNORE;
  194.                     break;
  195.                 }
  196.  
  197.                 data->active = button;
  198.                 o = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,button);
  199.                 set(o,MUIA_Selected,TRUE);
  200.  
  201.                 for (i = 0; i<nb; i++)
  202.                     if (exclude & (1<<i))
  203.                     {
  204.                         register Object *oo = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,i);
  205.                         ULONG           sel;
  206.  
  207.                         get(oo,MUIA_Selected,&sel);
  208.                         if (sel) set(oo,MUIA_Selected,FALSE);
  209.                     }
  210.  
  211.                 break;
  212.             }
  213.         }
  214.     }
  215.  
  216.     return DoSuperMethodA(cl,obj,(Msg)msg);
  217. }
  218.  
  219. /***********************************************************************/
  220. /*
  221. ** Bar Class OM_DISPOSE method
  222. */
  223.  
  224. static ASM ULONG
  225. mDispose(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  226. {
  227.     register struct data *data = INST_DATA(cl,obj);
  228.  
  229.     FreeVec(data->specials);
  230.     return DoSuperMethodA(cl,obj,msg);
  231. }
  232.  
  233. /***********************************************************************/
  234. /*
  235. ** Bar Class MUIM_Bar_Set method
  236. */
  237.  
  238. static ASM ULONG
  239. mBarSet(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Set *msg)
  240. {
  241.     register struct data    *data = INST_DATA(cl,obj);
  242.     register ULONG          button = msg->button;
  243.     register Object         *o;
  244.     register ULONG          tag, value;
  245.  
  246.     if (button>=data->nb) return 0;
  247.     o = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,button);
  248.  
  249.     set(o,tag = msg->tag,value = msg->value);
  250.  
  251.     if (msg->remember)
  252.     {
  253.         register struct special *specials = data->specials;
  254.  
  255.         switch (tag)
  256.         {
  257.             case MUIA_Disabled:
  258.                 if (value) specials[button].flags |= SFLG_Disabled;
  259.                 else specials[button].flags &= ~SFLG_Disabled;
  260.                 break;
  261.  
  262.             default:
  263.                 break;
  264.         }
  265.     }
  266.  
  267.     return 1;
  268. }
  269.  
  270. /***********************************************************************/
  271. /*
  272. ** Bar Class MUIM_Bar_Disabled method
  273. */
  274.  
  275. static ASM ULONG
  276. mBarDisable(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Disable *msg)
  277. {
  278.     register struct data    *data = INST_DATA(cl,obj);
  279.     register ULONG          disable = msg->disable;
  280.  
  281.     if (!BOOLSAME(data->flags & FLG_Disabled,disable))
  282.     {
  283.         register struct special *specials = data->specials;
  284.         register ULONG          nb = data->nb;
  285.         register int            i;
  286.  
  287.         for (i = 0; i<nb; i++)
  288.         {
  289.             register Object *o;
  290.  
  291.             if (specials[i].flags & SFLG_Skip) continue;
  292.  
  293.             o = (Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,i);
  294.  
  295.             if (disable)
  296.             {
  297.                 ULONG dis;
  298.  
  299.                 get(o,MUIA_Disabled,&dis);
  300.                 if (dis) specials[i].flags |= SFLG_Disabled;
  301.                 else specials[i].flags &= ~SFLG_Disabled;
  302.  
  303.                 set(o,MUIA_Disabled,TRUE);
  304.             }
  305.             else set(o,MUIA_Disabled,specials[i].flags & SFLG_Disabled);
  306.         }
  307.  
  308.         if (disable) data->flags |= FLG_Disabled;
  309.         else data->flags &= ~FLG_Disabled;
  310.     }
  311.  
  312.     return 0;
  313. }
  314.  
  315. /***********************************************************************/
  316. /*
  317. ** Bar Class MUIM_Bar_Notify method
  318. */
  319.  
  320. static ASM ULONG
  321. mBarNotify(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Notify *msg)
  322. {
  323.     register struct data    *data = INST_DATA(cl,obj);
  324.     register ULONG          button = msg->button, res;
  325.  
  326.     if (button>=data->nb) return 0;
  327.  
  328.     msg->button = MUIM_Notify;
  329.     res = DoMethodA((Object *)DoSuperMethod(cl,obj,MUIM_SpeedBar_GetObject,button),(Msg)&msg->button);
  330.     msg->button = button;
  331.  
  332.     return res;
  333. }
  334.  
  335. /***********************************************************************/
  336. /*
  337. ** Bar Class MUIM_Bar_Active method
  338. */
  339.  
  340. static ASM ULONG
  341. mBarActive(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) struct MUIP_Bar_Active *msg)
  342. {
  343.     return nfset(obj,MUIA_Bar_Active,msg->button);
  344. }
  345.  
  346. /***********************************************************************/
  347. /*
  348. ** Bar Class dispatcher
  349. */
  350.  
  351. static ULONG SAVEDS ASM
  352. dispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  353. {
  354.     switch(msg->MethodID)
  355.     {
  356.         case OM_NEW:           return mNew(cl,obj,(APTR)msg);
  357.         case OM_GET:           return mGet(cl,obj,(APTR)msg);
  358.         case OM_SET:           return mSets(cl,obj,(APTR)msg);
  359.         case OM_DISPOSE:       return mDispose(cl,obj,(APTR)msg);
  360.         case MUIM_Bar_Set:     return mBarSet(cl,obj,(APTR)msg);
  361.         case MUIM_Bar_Notify:  return mBarNotify(cl,obj,(APTR)msg);
  362.         case MUIM_Bar_Disable: return mBarDisable(cl,obj,(APTR)msg);
  363.         case MUIM_Bar_Active:  return mBarActive(cl,obj,(APTR)msg);
  364.         default:               return DoSuperMethodA(cl,obj,msg);
  365.     }
  366. }
  367.  
  368. /***********************************************************************/
  369. /*
  370. ** Bar Class create
  371. */
  372.  
  373. BOOL ASM
  374. createBarClass(REG(a0) struct MUI_CustomClass **class)
  375. {
  376.     return (BOOL)(*class = MUI_CreateCustomClass(NULL,MUIC_SpeedBar,NULL,sizeof(struct data),dispatcher));
  377. }
  378.  
  379. /***********************************************************************/
  380. /*
  381. ** Bar Class delete
  382. */
  383.  
  384. void ASM
  385. deleteBarClass(REG(a0) struct MUI_CustomClass **class)
  386. {
  387.         MUI_DeleteCustomClass(*class);
  388. }
  389.  
  390. /***********************************************************************/
  391.